package com.ttbj.shiro.realm;

import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ttbj.api.dto.PermissionDto;
import com.ttbj.api.dto.SalesmanDto;
import com.ttbj.api.exception.BusinessException;
import com.ttbj.api.salesman.PermissionService;
import com.ttbj.api.salesman.SalesmanService;
import com.ttbj.constant.Const;
import com.ttbj.constant.SalesmanEnum;



@Component
public class MemberRealm extends AuthorizingRealm {

	
	
	@Autowired
	private SalesmanService salesmanService;
	@Autowired
	private PermissionService permissionService;
	
	private Logger logger = LoggerFactory.getLogger(MemberRealm.class);
	
	/**
	 * 用于认证的方法
	 * @param token
	 * @return
	 * @throws AuthenticationException
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		logger.info("1.用户登录认证*******************doGetAuthenticationInfo");
		//登录认证的方法需要先执行，需要用他来判断登录用户的信息是否合法
		String username = (String) token.getPrincipal();
		String password = new String((char[]) token.getCredentials());
		
		SalesmanDto salesmanDto = null;
		int isDel = 1;
		try {
			salesmanDto = this.salesmanService.login(username, password);
			//获取查询出的del
			isDel = salesmanDto.getSalesmanIsDelete();
		} catch (BusinessException e) {
			return null;
		}
		//枚举的delCode
		int salesmanEnumCode = SalesmanEnum.NOT_DELETE.getCode();
		if (null != salesmanDto && isDel == salesmanEnumCode) {
			Session session = SecurityUtils.getSubject().getSession();
			session.setAttribute(Const.TTBJ_USER_SESSION_KEY, salesmanDto);
			//盐值加密，使用用户名作为盐值
			ByteSource credentialsSalt = ByteSource.Util.bytes(username);
			//注意：SimpleAuthenticationInfo() 传入的密码参数应该是数据库里的密码
			AuthenticationInfo auth = new SimpleAuthenticationInfo(username, salesmanDto.getSalesmanPwd(), credentialsSalt, super.getName());
			return auth;
		}
		return null;
	}
	
	/**
	 * 用户授权的方法
	 * @param principals 身份集合
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		logger.info("2.用户角色与权限*******************doGetAuthorizationInfo");
		//从PrincipalCollection 中获取登录用户的信息
		String userName = (String) principals.getPrimaryPrincipal();	//取得用户名
		SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo();	//定义授权信息
		
		SalesmanDto salesmanDto = this.salesmanService.findRoleNameByName(userName);
		//获取角色名称
		String roleName = salesmanDto.getRoleDto().getRoleName();
		//增加角色
		auth.addRole(roleName);
		//通过角色ID，查询角色对应的所有权限资源
		List<PermissionDto> permissionDtoList = this.permissionService.queryPermissionByRoleId(salesmanDto.getRoleDto().getId());
		for (PermissionDto permissionDto : permissionDtoList) {
            //添加权限
            auth.addStringPermission(permissionDto.getPermission());
            logger.info("roleName为{}，拥有的 permissionName是{}，permission是{}", 
            			roleName, permissionDto.getPermissionName(), permissionDto.getPermission());
        }
		return auth;
	}
}
